/*******************************************************************************
 *
 *    Copyright (c) Baina Info Tech Co. Ltd
 *
 *    MoboTap Client
 * 
 *    DummySSLSocketFactory
 *
 *    @author: chzhong
 *    @since:  2010-8-26
 *    @version: 1.0
 *
 ******************************************************************************/

package com.sdk.network;

import java.io.IOException;
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.net.Socket;
import java.net.UnknownHostException;

import javax.net.ssl.HttpsURLConnection;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSocket;
import javax.net.ssl.TrustManager;

import org.apache.http.conn.ConnectTimeoutException;
import org.apache.http.conn.scheme.LayeredSocketFactory;
import org.apache.http.params.HttpConnectionParams;
import org.apache.http.params.HttpParams;

/**
 * DummySSLSocketFactory of MoboTap Client.
 * @author chzhong
 *
 */
public class DummySSLSocketFactory implements LayeredSocketFactory  {

    private javax.net.ssl.SSLSocketFactory mFactory = HttpsURLConnection.getDefaultSSLSocketFactory();


    /**
     * Initiate a new instance of {@link DummySSLSocketFactory}.
     */
    public DummySSLSocketFactory () {
        try
        {
            final SSLContext context = SSLContext.getInstance ("TLS");
            final TrustManager[] tm = new TrustManager[] { new DummyTrustManager() };
            context.init (null, tm, null);

            mFactory = context.getSocketFactory ();
        }
        catch (final Exception e)
        {
            e.printStackTrace();
        }
    }


    /* (non-Javadoc)
     * @see org.apache.http.conn.scheme.SocketFactory#createSocket()
     */
    @Override
    public Socket createSocket() throws IOException {
        return mFactory.createSocket();
    }


    /* (non-Javadoc)
     * @see org.apache.http.conn.scheme.SocketFactory#connectSocket(java.net.Socket, java.lang.String, int, java.net.InetAddress, int, org.apache.http.params.HttpParams)
     */
    @Override
    public Socket connectSocket(final Socket sock, final String host, final int port,
            final InetAddress localAddress, int localPort, final HttpParams params)
    throws IOException, UnknownHostException, ConnectTimeoutException {
        if (host == null) {
            throw new IllegalArgumentException("Target host may not be null.");
        }
        if (params == null) {
            throw new IllegalArgumentException("Parameters may not be null.");
        }

        final SSLSocket sslsock = (SSLSocket)
        ((sock != null) ? sock : createSocket());

        if ((localAddress != null) || (localPort > 0)) {

            // we need to bind explicitly
            if (localPort < 0)
            {
                localPort = 0; // indicates "any"
            }

            final InetSocketAddress isa =
                new InetSocketAddress(localAddress, localPort);
            sslsock.bind(isa);
        }

        final int connTimeout = HttpConnectionParams.getConnectionTimeout(params);
        final int soTimeout = HttpConnectionParams.getSoTimeout(params);

        InetSocketAddress remoteAddress;
        remoteAddress = new InetSocketAddress(host, port);

        sslsock.connect(remoteAddress, connTimeout);

        sslsock.setSoTimeout(soTimeout);

        return sslsock;
    }


    /* (non-Javadoc)
     * @see org.apache.http.conn.scheme.SocketFactory#isSecure(java.net.Socket)
     */
    @Override
    public boolean isSecure(final Socket sock) throws IllegalArgumentException {
        if (sock == null) {
            throw new IllegalArgumentException("Socket may not be null.");
        }
        // This instanceof check is in line with createSocket() above.
        if (!(sock instanceof SSLSocket)) {
            throw new IllegalArgumentException
            ("Socket not created by this factory.");
        }
        // This check is performed last since it calls the argument object.
        if (sock.isClosed()) {
            throw new IllegalArgumentException("Socket is closed.");
        }

        return true;
    }


    /* (non-Javadoc)
     * @see org.apache.http.conn.scheme.LayeredSocketFactory#createSocket(java.net.Socket, java.lang.String, int, boolean)
     */
    @Override
    public Socket createSocket(final Socket socket, final String host, final int port,
            final boolean autoClose) throws IOException, UnknownHostException {
        final SSLSocket sslSocket = (SSLSocket) this.mFactory.createSocket(
                                                                           socket,
                                                                           host,
                                                                           port,
                                                                           autoClose
        );
        return sslSocket;
    }


}
